#include <bits/stdc++.h>

using namespace std;

// 插入、删除和获取随机元素O(1)时间且允许有重复数字的结构
// 测试链接 : https://leetcode.cn/problems/insert-delete-getrandom-o1-duplicates-allowed/

class RandomizedCollection 
{
private:
    unordered_map<int, unordered_set<int>> m;
    vector<int> v;

public:
    RandomizedCollection() 
    {
        srand(time(nullptr));
    }
    
    bool insert(int val) 
    {
        bool flag = true;
        if(m.count(val)) flag = false; // val 已经存在
        m[val].emplace(v.size());
        v.emplace_back(val);
        return flag;
    }
    
    bool remove(int val) 
    {
        if(!m.count(val)) return false;
        unordered_set<int>& valSet = m[val];
        int pos = *valSet.begin();
        int endValue = v.back();
        if(val == endValue) // 数组最后一个元素就是 val
        {
            valSet.erase(v.size() - 1); // 直接删除即可
        }
        else // 数组最后一个元素不是 val，需要进行位置交换
        {
            unordered_set<int>& endValueSet = m[endValue];
            endValueSet.emplace(pos);
            v[pos] = endValue;
            endValueSet.erase(v.size() - 1);
            valSet.erase(pos);
        }
        v.pop_back();
        if(valSet.empty()) m.erase(val);

        return true;    
    }
    
    int getRandom() 
    {
        return v[rand() % v.size()];
    }
};